<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en-US">
<head>
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=11"/>
<meta name="generator" content="Doxygen 1.13.2"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<title>CAD_Doc: Using GoogleTest from various build systems</title>
<link href="tabs.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript" src="dynsections.js"></script>
<script type="text/javascript" src="clipboard.js"></script>
<link href="navtree.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="navtreedata.js"></script>
<script type="text/javascript" src="navtree.js"></script>
<script type="text/javascript" src="resize.js"></script>
<script type="text/javascript" src="cookie.js"></script>
<link href="search/search.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="search/searchdata.js"></script>
<script type="text/javascript" src="search/search.js"></script>
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
  $(function() { init_search(); });
/* @license-end */
</script>
<link href="doxygen.css" rel="stylesheet" type="text/css" />
</head>
<body>
<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
<div id="titlearea">
<table cellspacing="0" cellpadding="0">
 <tbody>
 <tr id="projectrow">
  <td id="projectalign">
   <div id="projectname">CAD_Doc<span id="projectnumber">&#160;1.0</span>
   </div>
   <div id="projectbrief">cad synopsis</div>
  </td>
    <td>        <div id="MSearchBox" class="MSearchBoxInactive">
        <span class="left">
          <span id="MSearchSelect"                onmouseover="return searchBox.OnSearchSelectShow()"                onmouseout="return searchBox.OnSearchSelectHide()">&#160;</span>
          <input type="text" id="MSearchField" value="" placeholder="Search" accesskey="S"
               onfocus="searchBox.OnSearchFieldFocus(true)" 
               onblur="searchBox.OnSearchFieldFocus(false)" 
               onkeyup="searchBox.OnSearchFieldChange(event)"/>
          </span><span class="right">
            <a id="MSearchClose" href="javascript:searchBox.CloseResultsWindow()"><img id="MSearchCloseImg" border="0" src="search/close.svg" alt=""/></a>
          </span>
        </div>
</td>
 </tr>
 </tbody>
</table>
</div>
<!-- end header part -->
<!-- Generated by Doxygen 1.13.2 -->
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
var searchBox = new SearchBox("searchBox", "search/",'.html');
/* @license-end */
</script>
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
$(function() { codefold.init(0); });
/* @license-end */
</script>
</div><!-- top -->
<div id="side-nav" class="ui-resizable side-nav-resizable">
  <div id="nav-tree">
    <div id="nav-tree-contents">
      <div id="nav-sync" class="sync"></div>
    </div>
  </div>
  <div id="splitbar" style="-moz-user-select:none;" 
       class="ui-resizable-handle">
  </div>
</div>
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
$(function(){initNavTree('md__build_2__deps_2googletest-src_2docs_2pkgconfig.html',''); initResizable(true); });
/* @license-end */
</script>
<div id="doc-content">
<!-- window showing the filter options -->
<div id="MSearchSelectWindow"
     onmouseover="return searchBox.OnSearchSelectShow()"
     onmouseout="return searchBox.OnSearchSelectHide()"
     onkeydown="return searchBox.OnSearchSelectKey(event)">
</div>

<!-- iframe showing the search results (closed by default) -->
<div id="MSearchResultsWindow">
<div id="MSearchResults">
<div class="SRPage">
<div id="SRIndex">
<div id="SRResults"></div>
<div class="SRStatus" id="Loading">Loading...</div>
<div class="SRStatus" id="Searching">Searching...</div>
<div class="SRStatus" id="NoMatches">No Matches</div>
</div>
</div>
</div>
</div>

<div><div class="header">
  <div class="headertitle"><div class="title">Using GoogleTest from various build systems</div></div>
</div><!--header-->
<div class="contents">
<div class="textblock"><p><a class="anchor" id="autotoc_md216"></a></p>
<p>GoogleTest comes with pkg-config files that can be used to determine all necessary flags for compiling and linking to GoogleTest (and GoogleMock). Pkg-config is a standardised plain-text format containing</p>
<ul>
<li>the includedir (-I) path</li>
<li>necessary macro (-D) definitions</li>
<li>further required flags (-pthread)</li>
<li>the library (-L) path</li>
<li>the library (-l) to link to</li>
</ul>
<p>All current build systems support pkg-config in one way or another. For all examples here we assume you want to compile the sample <code>samples/sample3_unittest.cc</code>.</p>
<h2><a class="anchor" id="autotoc_md217"></a>
CMake</h2>
<p>Using <code>pkg-config</code> in CMake is fairly easy:</p>
<div class="fragment"><div class="line">cmake_minimum_required(VERSION 3.0)</div>
<div class="line"> </div>
<div class="line">cmake_policy(SET CMP0048 NEW)</div>
<div class="line">project(my_gtest_pkgconfig VERSION 0.0.1 LANGUAGES CXX)</div>
<div class="line"> </div>
<div class="line">find_package(PkgConfig)</div>
<div class="line">pkg_search_module(GTEST REQUIRED gtest_main)</div>
<div class="line"> </div>
<div class="line">add_executable(testapp samples/sample3_unittest.cc)</div>
<div class="line">target_link_libraries(testapp ${GTEST_LDFLAGS})</div>
<div class="line">target_compile_options(testapp PUBLIC ${GTEST_CFLAGS})</div>
<div class="line"> </div>
<div class="line">include(CTest)</div>
<div class="line">add_test(first_and_only_test testapp)</div>
</div><!-- fragment --><p>It is generally recommended that you use <code>target_compile_options</code> + <code>_CFLAGS</code> over <code>target_include_directories</code> + <code>_INCLUDE_DIRS</code> as the former includes not just -I flags (GoogleTest might require a macro indicating to internal headers that all libraries have been compiled with threading enabled. In addition, GoogleTest might also require <code>-pthread</code> in the compiling step, and as such splitting the pkg-config <code>Cflags</code> variable into include dirs and macros for <code>target_compile_definitions()</code> might still miss this). The same recommendation goes for using <code>_LDFLAGS</code> over the more commonplace <code>_LIBRARIES</code>, which happens to discard <code>-L</code> flags and <code>-pthread</code>.</p>
<h2><a class="anchor" id="autotoc_md218"></a>
Help! pkg-config can't find GoogleTest!</h2>
<p>Let's say you have a <code>CMakeLists.txt</code> along the lines of the one in this tutorial and you try to run <code>cmake</code>. It is very possible that you get a failure along the lines of:</p>
<div class="fragment"><div class="line">-- Checking for one of the modules &#39;gtest_main&#39;</div>
<div class="line">CMake Error at /usr/share/cmake/Modules/FindPkgConfig.cmake:640 (message):</div>
<div class="line">  None of the required &#39;gtest_main&#39; found</div>
</div><!-- fragment --><p>These failures are common if you installed GoogleTest yourself and have not sourced it from a distro or other package manager. If so, you need to tell pkg-config where it can find the <code>.pc</code> files containing the information. Say you installed GoogleTest to <code>/usr/local</code>, then it might be that the <code>.pc</code> files are installed under <code>/usr/local/lib64/pkgconfig</code>. If you set</p>
<div class="fragment"><div class="line">export PKG_CONFIG_PATH=/usr/local/lib64/pkgconfig</div>
</div><!-- fragment --><p>pkg-config will also try to look in <code>PKG_CONFIG_PATH</code> to find <code>gtest_main.pc</code>.</p>
<h2><a class="anchor" id="autotoc_md219"></a>
Using pkg-config in a cross-compilation setting</h2>
<p>Pkg-config can be used in a cross-compilation setting too. To do this, let's assume the final prefix of the cross-compiled installation will be <code>/usr</code>, and your sysroot is <code>/home/MYUSER/sysroot</code>. Configure and install GTest using</p>
<div class="fragment"><div class="line">mkdir build &amp;&amp; cmake -DCMAKE_INSTALL_PREFIX=/usr ..</div>
</div><!-- fragment --><p>Install into the sysroot using <code>DESTDIR</code>:</p>
<div class="fragment"><div class="line">make -j install DESTDIR=/home/MYUSER/sysroot</div>
</div><!-- fragment --><p>Before we continue, it is recommended to <b>always</b> define the following two variables for pkg-config in a cross-compilation setting:</p>
<div class="fragment"><div class="line">export PKG_CONFIG_ALLOW_SYSTEM_CFLAGS=yes</div>
<div class="line">export PKG_CONFIG_ALLOW_SYSTEM_LIBS=yes</div>
</div><!-- fragment --><p>otherwise <code>pkg-config</code> will filter <code>-I</code> and <code>-L</code> flags against standard prefixes such as <code>/usr</code> (see <a href="https://bugs.freedesktop.org/show_bug.cgi?id=28264#c3">https://bugs.freedesktop.org/show_bug.cgi?id=28264#c3</a> for reasons why this stripping needs to occur usually).</p>
<p>If you look at the generated pkg-config file, it will look something like</p>
<div class="fragment"><div class="line">libdir=/usr/lib64</div>
<div class="line">includedir=/usr/include</div>
<div class="line"> </div>
<div class="line">Name: gtest</div>
<div class="line">Description: GoogleTest (without main() function)</div>
<div class="line">Version: 1.11.0</div>
<div class="line">URL: https://github.com/google/googletest</div>
<div class="line">Libs: -L${libdir} -lgtest -lpthread</div>
<div class="line">Cflags: -I${includedir} -DGTEST_HAS_PTHREAD=1 -lpthread</div>
</div><!-- fragment --><p>Notice that the sysroot is not included in <code>libdir</code> and <code>includedir</code>! If you try to run <code>pkg-config</code> with the correct <code>PKG_CONFIG_LIBDIR=/home/MYUSER/sysroot/usr/lib64/pkgconfig</code> against this <code>.pc</code> file, you will get</p>
<div class="fragment"><div class="line">$ pkg-config --cflags gtest</div>
<div class="line">-DGTEST_HAS_PTHREAD=1 -lpthread -I/usr/include</div>
<div class="line">$ pkg-config --libs gtest</div>
<div class="line">-L/usr/lib64 -lgtest -lpthread</div>
</div><!-- fragment --><p>which is obviously wrong and points to the <code>CBUILD</code> and not <code>CHOST</code> root. In order to use this in a cross-compilation setting, we need to tell pkg-config to inject the actual sysroot into <code>-I</code> and <code>-L</code> variables. Let us now tell pkg-config about the actual sysroot</p>
<div class="fragment"><div class="line">export PKG_CONFIG_DIR=</div>
<div class="line">export PKG_CONFIG_SYSROOT_DIR=/home/MYUSER/sysroot</div>
<div class="line">export PKG_CONFIG_LIBDIR=${PKG_CONFIG_SYSROOT_DIR}/usr/lib64/pkgconfig</div>
</div><!-- fragment --><p>and running <code>pkg-config</code> again we get</p>
<div class="fragment"><div class="line">$ pkg-config --cflags gtest</div>
<div class="line">-DGTEST_HAS_PTHREAD=1 -lpthread -I/home/MYUSER/sysroot/usr/include</div>
<div class="line">$ pkg-config --libs gtest</div>
<div class="line">-L/home/MYUSER/sysroot/usr/lib64 -lgtest -lpthread</div>
</div><!-- fragment --><p>which contains the correct sysroot now. For a more comprehensive guide to also including <code>${CHOST}</code> in build system calls, see the excellent tutorial by Diego Elio Pettenò: <a href="https://autotools.io/pkgconfig/cross-compiling.html">https://autotools.io/pkgconfig/cross-compiling.html</a> </p>
</div></div><!-- contents -->
</div><!-- PageDoc -->
</div><!-- doc-content -->
<!-- start footer part -->
<div id="nav-path" class="navpath"><!-- id is needed for treeview function! -->
  <ul>
    <li class="footer">Generated by <a href="https://www.doxygen.org/index.html"><img class="footer" src="doxygen.svg" width="104" height="31" alt="doxygen"/></a> 1.13.2 </li>
  </ul>
</div>
</body>
</html>
